import bge

# This script runs continuously. The main function is to refresh the tag
# coordinates from the surface table, by reading the database textfile. It also
# takes care of detecting tags in a certain area of the table, for instance to remove
# them from a scene. 
#
# If you have other things that need continuous updates (maybe UI functions), you could
# put them here as well
#

obj = []
matrix = []

scene = bge.logic.getCurrentScene()
cont = bge.logic.getCurrentController() 
own = cont.owner
outfile = str(own['file'])

# I used bge.Cam to store the current selected camera. Make sure these camera's are
# available in your scene, and change them through key press or something
if bge.Cam == "topview": 
	scene.active_camera = "TopView"
if bge.Cam == "rotview": 
	scene.active_camera = "RotView"
if bge.Cam == "fpsview": 
	scene.active_camera = "FPSView"


# Here we read new coordinates from 'file'. This 'file' is maintained by an SQL 
# database that is connected to the surface table. We use this file to make sure 
# that the Blender application can run without external libraries (alternatively
# you could import a Python SQL library here to do it directly).
#
#
# [Surface Table] --->  [SQL Database] ---> [sql.dat file]
#
#
# An external script called sql.py takes care of constantly reading database values
# and storing them in sql.dat (which 'file' refers to in Blender)

# Read the database file and put coordinates in 'matrix'
FILE = open(outfile,"r")
matrix = FILE.readlines()
FILE.close()

# Extract coordinates and tag names from matrix
for line in matrix:
	line = line.strip("\n")
	line = line.strip("\r")
	line = line.split(",")
	# 'Item' contains a sequence number, X, Y, rotation, and TagName
	# 'Obj' will contain all individual items (tag info)
	item = [ int(line[0]), int(line[1]), int(line[2]), int(line[3]), str(line[4])]
	obj += [item]
	
	
# For all tags in 'obj', connect coordinates to appropriate Blender objects
#
# It is useful to use Blender empties as tag references. So create a group of 
# empties called 'C0', 'C1', 'C2', etc. Connect the actual models/objects to these
# empties. This construction allows you to easily remove and add objects to empties 
# in-game, which is useful when you want some more dynamic applications (e.g. remove
# objects, change models on the fly, etc.)
#
#

for i in obj:
	naam = "%s" %(i[4])
	obj = scene.objects[naam]
	# The following detects objects near the left side of the table
	if i[1] < 50 and i[2] < 650:
		bge.GUI = 1
		bge.selModel = naam
	if i[1] >= 50 and bge.GUI != 1 and bge.GUI != 2:
		bge.GUI = 0
	x = (1024- i[1]) / 50
	y = ( i[2]) / 50
	obj.localPosition = [x,y,.5]
	deg = i[3]
	rad = (3.14 /180) * (deg - 90)
	x = (3.14 / 180) * 90
	obj.worldOrientation=[0,0, -rad]
	# The following detects objects in the lower left corner of the table
	if i[1] < 50 and i[2] > 650: 
		#Remove this object from scene
		scene.objects[naam].children[0].endObject()
		parObj = scene.objects["Control"]
		addObj = scene.objects["DefaultModel"]
		newObj = scene.addObject(addObj, parObj)
		# I use 'init' to be able to distinguish real models from clones (added by AddObject())
		if 'init' in newObj:
			newObj['init'] = 1
		newObj.position = scene.objects[bge.selModel].position
		newObj.worldOrientation= scene.objects[bge.selModel].orientation					
		# Here we allow models to use their own scaling
		if 'scale' in newObj:
			print ("   * This object has individual scaling")
			newObj.localScale = [newObj['scale'], newObj['scale'], newObj['scale'] ]
		else:
			newObj.localScale = [1,1,1]	  
		newObj.setParent(scene.objects[naam])
		newObj.visible = False
